package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.mapper.CartInfoMapper;
import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartInfoMapper cartInfoMapper;
    @Autowired
    private ProductFeignClient productFeignClient;

    @Override
    public CartInfo addToCart(Long skuId, Integer skuNum) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //用户ID
        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(userId)) {
            //临时用户ID
            userId = AuthContextHolder.getUserTempId(request);
        }
        CartInfo cartInfo = cartInfoMapper.selectOne(
                new QueryWrapper<CartInfo>().eq("sku_id", skuId).eq("user_id", userId));
        if (null != cartInfo) {
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //查实时价格
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            cartInfo.setSkuPrice(skuPrice);
            cartInfo.setIsChecked(1);
            cartInfoMapper.updateById(cartInfo);
        } else {
            cartInfo = new CartInfo();
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setSkuPrice(skuInfo.getPrice());
            cartInfoMapper.insert(cartInfo);
        }
        return cartInfo;
    }

    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        //判断是否已经登录
        if (!StringUtils.isEmpty(userId)) {
            //登录
            //临时用户的购物车  用户的购物车
            return mergeCartList(this.cartList(userId), this.cartList(userTempId), userTempId,userId);
        } else {
            //未登录
            //临时用户的购物车
            return this.cartList(userTempId);
        }
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked, String userId) {
        CartInfo cartInfo = new CartInfo();
        cartInfo.setIsChecked(isChecked);
        cartInfoMapper.update(cartInfo,new QueryWrapper<CartInfo>().eq("user_id",userId).eq("sku_id",skuId));
    }

    @Override
    public void deleteCart(Long skuId, String userId) {
        cartInfoMapper.delete(new QueryWrapper<CartInfo>().eq("user_id",userId).eq("sku_id",skuId));

    }

    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(
                new QueryWrapper<CartInfo>().eq("user_id", userId).eq("is_checked", 1));
        cartInfoList.forEach(c -> {
            BigDecimal skuPrice = productFeignClient.getSkuPrice(c.getSkuId());
            c.setSkuPrice(skuPrice);
        });
        return cartInfoList;
    }

    private List<CartInfo> mergeCartList(List<CartInfo> cartListUserId, List<CartInfo> cartListUserTempId
            , String userTempId,String userId) {
        if(!CollectionUtils.isEmpty(cartListUserId)){
            if(!CollectionUtils.isEmpty(cartListUserTempId)){
                Map<Long, CartInfo> cartInfoUserIdMap = cartListUserId.stream()
                        .collect(Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));
                cartListUserTempId.forEach((cartInfo) -> {
                    Long skuId = cartInfo.getSkuId();
                    if(cartInfoUserIdMap.containsKey(skuId)){
                        CartInfo cartInfo1 = cartInfoUserIdMap.get(skuId);
                        cartInfo1.setSkuNum(cartInfo1.getSkuNum() + cartInfo.getSkuNum());
                        cartInfoMapper.updateById(cartInfo1);
                    }else{
                        cartInfoUserIdMap.put(cartInfo.getSkuId(),cartInfo);
                        cartInfo.setUserId(userId);
                        cartInfoMapper.updateById(cartInfo);
                    }

                });
                List<Long> ids = cartListUserTempId.stream().map(CartInfo::getId).collect(Collectors.toList());
                cartInfoMapper.deleteBatchIds(ids);
                Collection<CartInfo> values = cartInfoUserIdMap.values();
                return new ArrayList<>(values);
            }else{
                return cartListUserId;
            }
        }else{
            if(!CollectionUtils.isEmpty(cartListUserTempId)){
                CartInfo cartInfo = new CartInfo();
                cartInfo.setUserId(userId);
                cartInfoMapper.update(cartInfo,new QueryWrapper<CartInfo>().eq("user_id",userTempId));
                return cartListUserTempId;
            }else{
                return new ArrayList<CartInfo>();
            }
        }
    }

    private List<CartInfo> cartList(String userId) {
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(new QueryWrapper<CartInfo>().eq("user_id", userId));
        //更新价格
        if(!CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList.forEach(cart -> {
                BigDecimal skuPrice = productFeignClient.getSkuPrice(cart.getSkuId());
                cart.setSkuPrice(skuPrice);
            });
        }
        return cartInfoList;
    }
}
